#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(void)
{
    // 1.创建服务器对象
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);


    // 使套接字sockfd关联的地址在套接字关闭后立即释放
    int on = 1;
    setsockopt(tcp_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));  //开启端口复用功能 

    // 2.绑定服务器地址
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定所有网卡
    if (bind(tcp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("绑定失败\n");
        return -1;
    }
    // 3.设置监听模式
    if (listen(tcp_socket, 5) < 0)
    {
        perror("监听失败\n");
        return -1;
    }

    while (1)
    {
        // 接收客户端的链接请求
        struct sockaddr_in clien_addr; // 存放客户端的地址信息
        int add_len = sizeof(clien_addr);

        int new_socket = accept(tcp_socket, (struct sockaddr *)&clien_addr, &add_len);
        if (new_socket <= 0)
        {
            perror("接收失败\n");
            return -1;
        }

        // char *inet_ntoa(struct in_addr in);  //把网络地址转换为字符串地址
        // 检索客户端的地址信息
        char *ip = inet_ntoa(clien_addr.sin_addr);
        // uint16_t ntohs(uint16_t netshort);   //把网络端口转换为本地端口
        int port = ntohs(clien_addr.sin_port);

        printf("客户端的地址信息：%s:%d:new_socket=%d\n", ip, port, new_socket);
    }
}